package com.atguigu.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.common.utils.HttpUtils;
import com.atguigu.gulimall.member.dao.MemberLevelDao;
import com.atguigu.gulimall.member.entity.MemberLevelEntity;
import com.atguigu.gulimall.member.exception.PhoneExistException;
import com.atguigu.gulimall.member.exception.UserNameExistException;
import com.atguigu.gulimall.member.vo.MemberLoginVo;
import com.atguigu.gulimall.member.vo.MemberRegistVo;
import com.atguigu.gulimall.member.vo.SocialUser;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.member.dao.MemberDao;
import com.atguigu.gulimall.member.entity.MemberEntity;
import com.atguigu.gulimall.member.service.MemberService;
import org.springframework.util.StringUtils;
/**
 * 会员
 */
@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Autowired MemberLevelDao memberLevelDao;

    /**
     * 根据 token 获取用户信息
     */
    @Override
    public MemberEntity login(SocialUser socialUser) {
        MemberEntity entity = new MemberEntity();
        try {
            Map<String, String> query = new HashMap<>();
            query.put("access_token", socialUser.getAccess_token());
            //1、根据 token 查询用户信息
            HttpResponse response = HttpUtils.doGet(
                    "https://gitee.com", "/api/v5/user", "get", new HashMap<>(), query);

            if (response.getStatusLine().getStatusCode() == 200) {
                String string = EntityUtils.toString(response.getEntity());
                JSONObject jsonObject = JSON.parseObject(string);
                Integer uid = (Integer) jsonObject.get("id");

                //2、根据 uid 判断当前用户是否以前用社交平台登录过系统
                MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("uid", uid));
                if (!StringUtils.isEmpty(memberEntity)) {
                    //2.1 说明这个用户之前已经注册过，那就执行更新操作
                    MemberEntity member = new MemberEntity();
                    member.setId(memberEntity.getId());
                    member.setAccessToken(socialUser.getAccess_token());    //设置访问令牌
                    member.setExpiresIn(socialUser.getExpires_in());    //设置令牌过期时间
                    baseMapper.updateById(member);

                    memberEntity.setAccessToken(socialUser.getAccess_token());
                    memberEntity.setExpiresIn(socialUser.getExpires_in());
                    return memberEntity;
                } else {
                    //2.2 未找到则注册，根据社交平台的开放接口查询用户的开放信息存储到系统
                    String name = jsonObject.getString("name");    //昵称
                    String login = jsonObject.getString("login");    //登录名
                    // 等等信息......
                    entity.setNickname(name);
                    entity.setUsername(login);
                    entity.setUid(uid);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        entity.setExpiresIn(socialUser.getExpires_in());    //设置令牌过期时间
        entity.setAccessToken(socialUser.getAccess_token());    //设置访问令牌
        baseMapper.insert(entity);
        return entity;    //设置完后，返回当前实体用户信息
    }

    /**
     * 页面和数据库的密码匹配
     */
    @Override
    public MemberEntity login(MemberLoginVo vo) {
        String loginacct = vo.getLoginacct();
        String password = vo.getPassword();
        //去数据库查询
        MemberEntity memberEntity = baseMapper.selectOne(
                //根据 用户名 或者 手机号 查询单条信息
                new QueryWrapper<MemberEntity>().eq("username", loginacct).or().eq("mobile", loginacct));
        if (memberEntity == null) {
            //数据库没有当前用户，登录失败
            return null;
        } else {
            //获取到数据库的 password
            String passwordDB = memberEntity.getPassword();
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();    //密码编码器
            //密码匹配
            boolean matches = passwordEncoder.matches(password, passwordDB);
            if (matches) {
                return memberEntity;
            } else {
                return null;
            }
        }
    }


    /**
     * 账户注册后，保存基本会员信息
     */
    @Override
    public void regist(MemberRegistVo vo) {
        MemberEntity entity = new MemberEntity();
        //设置默认等级
        MemberLevelEntity levelEntity = memberLevelDao.getDefaultLevel();    //调用《查询普通会员》方法
        entity.setLevelId(levelEntity.getId());

        //检查用户名和手机号是否唯一。为了让 controller 能感知异常，异常机制
        checkPhoneUnique(vo.getPhone());    //调用《检查手机号是否唯一》方法
        checkUserNameUnique(vo.getUserName());    //调用《检查用户名是否唯一》方法

        entity.setMobile(vo.getPhone());
        entity.setUsername(vo.getUserName());
        entity.setNickname(vo.getUserName());    //设置昵称
        //密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(vo.getPassword());
        entity.setPassword(encode);
        //保存会员信息
        baseMapper.insert(entity);
    }

    /**
     * 检查手机号是否唯一
     */
    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count > 0) {
            throw new PhoneExistException();
        }
    }

    /**
     * 检查用户名是否唯一
     */
    @Override
    public void checkUserNameUnique(String userName) throws UserNameExistException {
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (count > 0) {
            throw new UserNameExistException();
        }
    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );
        return new PageUtils(page);
    }
}